package com.ruoyi.common.utils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;

import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class QrCodeUtil {

    /** 深灰模块色 */
    private static final int DARK_GRAY  = 0x9C9C9C;
    /** 浅灰背景色 */
    private static final int LIGHT_GRAY = 0xE4E4E4;

    /**
     * 生成简单二维码并输出到HTTP响应
     */
    public static void generateToResponse(String content, HttpServletResponse response) throws Exception {
        int size = 300;
        BufferedImage image = generateQRImage(content, size);

        response.setContentType("image/png");
        javax.imageio.ImageIO.write(image, "PNG", response.getOutputStream());
    }

    /**
     * 生成简单二维码并输出到HTTP响应
     */
    public static void generateDisabledToResponse(String content, HttpServletResponse response) throws Exception {
        int size = 300;
        BufferedImage image = generateDisabledQrImage(content, size);

        response.setContentType("image/png");
        javax.imageio.ImageIO.write(image, "PNG", response.getOutputStream());
    }

    /**
     * 生成二维码Base64字符串
     */
    public String generateBase64(String content) throws Exception {
        BufferedImage image = generateQRImage(content, 300);
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        javax.imageio.ImageIO.write(image, "PNG", outputStream);
        return "data:image/png;base64," + Base64.getEncoder().encodeToString(outputStream.toByteArray());
    }

    /**
     * 生成二维码图片
     */
    private static BufferedImage generateQRImage(String content, int size) throws WriterException {
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");      // 中文支持
        hints.put(EncodeHintType.MARGIN, 1);                   // 白边大小 1=最小

        QRCodeWriter writer = new QRCodeWriter();
        BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, size, size, hints);

        int w = bitMatrix.getWidth();
        int h = bitMatrix.getHeight();
        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);

        // 0xFFFFFF 白底，0x000000 黑码
        for (int x = 0; x < w; x++) {
            for (int y = 0; y < h; y++) {
                image.setRGB(x, y, bitMatrix.get(x, y) ? 0x000000 : 0xFFFFFF);
            }
        }
        return image;
    }

    /**
     * 生成“灰色无效”二维码，扫码无法识别
     *
     * @param content 任意文本（长度同普通二维码限制）
     * @param size    边长（像素）
     * @return BufferedImage 灰色二维码
     */
    public static BufferedImage generateDisabledQrImage(String content, int size) throws WriterException {
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.MARGIN, 1);

        QRCodeWriter writer = new QRCodeWriter();
        BitMatrix matrix = writer.encode(content, BarcodeFormat.QR_CODE, size, size, hints);

        int w = matrix.getWidth();
        int h = matrix.getHeight();
        BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);

        for (int x = 0; x < w; x++) {
            for (int y = 0; y < h; y++) {
                img.setRGB(x, y, matrix.get(x, y) ? DARK_GRAY : LIGHT_GRAY);
            }
        }
        return img;
    }
}
